package com.binance.amazon.s3.config;


import com.amazonaws.SDKGlobalConfiguration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.AmazonS3Encryption;
import com.amazonaws.services.s3.AmazonS3EncryptionClient;
import com.amazonaws.services.s3.AmazonS3EncryptionClientBuilder;
import com.amazonaws.services.s3.model.CryptoConfiguration;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.KMSEncryptionMaterialsProvider;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;



@Configuration
@Log4j2
public class AmazonS3Config implements EnvironmentAware {

    private Environment environment;

    @Value("${amazon.s3.accesskey:null}")
    private String accessKey;

    @Value("${amazon.s3.secretkey:null}")
    private String secretKey;

    @Value("${amazon.s3.region:null}")
    private String region;

    @Value("${amazon.s3.encrypt.key.id:null}")
    private String encryptKeyId;


    @Bean("AmazonS3")
    public AmazonS3 amazonS3() {
        System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");

        log.info("init AmazonS3Client with accessKey: {}, secretKey: {}, region: {}, encryptKeyId: {}",
                StringUtils.isEmpty(accessKey) ? "empty" : "not empty",
                StringUtils.isEmpty(secretKey) ? "empty" : "not empty",
                region);

        if (StringUtils.isEmpty(region)) {
            log.warn("S3 config: region is missing.");
            return null;
        }

        AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withRegion(region);
        //本地调试使用accessKey & secretKey的认证方式
        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(secretKey)) {
            log.info("accessKey或secretKey为空, EC2ContainerCredentialsProviderWrapper");
            builder.withCredentials(new EC2ContainerCredentialsProviderWrapper());
        } else {
            log.info("accessKey和secretKe不为空, 使用AWSStaticCredentialsProvider认证");
            builder.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)));
        }
        return builder.build();
    }



    @Bean("AmazonS3Encryption")
    public AmazonS3Encryption amazonS3Encryption() {
        System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");

        log.info("init AmazonS3Encryption with accessKey: {}, secretKey: {}, region: {}, encryptKeyId: {}",
                StringUtils.isEmpty(accessKey) ? "empty" : "not empty",
                StringUtils.isEmpty(secretKey) ? "empty" : "not empty",
                region,
                encryptKeyId);

        if (StringUtils.isEmpty(region) || StringUtils.isEmpty(encryptKeyId)) {
            log.warn("S3 config missing.");
            return null;
        }

        AmazonS3EncryptionClientBuilder builder = AmazonS3EncryptionClientBuilder.standard()
                .withCryptoConfiguration(new CryptoConfiguration(CryptoMode.AuthenticatedEncryption)
                        .withKmsRegion(Regions.fromName(region)))
                // Can either be Key ID or alias (prefixed with 'alias/')
                .withEncryptionMaterials(new KMSEncryptionMaterialsProvider(encryptKeyId))
                .withRegion(region);


        //本地调试使用accessKey & secretKey的认证方式
        log.info("init Amazon S3, region: {}", region);
        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(secretKey)) {
            log.info("accessKey或secretKey为空, EC2ContainerCredentialsProviderWrapper");
            builder.withCredentials(new EC2ContainerCredentialsProviderWrapper());
        } else {
            log.info("accessKey和secretKe不为空, 使用AWSStaticCredentialsProvider认证");
            builder.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)));
        }
        AmazonS3EncryptionClient s = (AmazonS3EncryptionClient) builder.build();
        return s;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
